RocksonLee's Blog
avatar
RocksonLee
2021-11-03 21:09:24
  • 本文总阅读量
查看原题

点击跳转

二次扫描 换根,难度不大

主要是扫描的时候,方程要对

每扫下一个点的时候,需要把前面的点的牛总数加上这条边,减去后面的点的牛总数乘上这条边

蓝属实有点过了qwq,推P3478,模板题

记得开long long

#include <bits/stdc++.h>
#define INF 0x3f3f3f3f3f3f3f3f
// 尼玛,开个ll记得把这里加多4个3f
#define N 100010
typedef long long ll;
using namespace std;

ll n,x,y,temp;
ll f[N],ans=INF;
ll c[N],qwq[N],size[N];// 尼玛,开个ll不会么
vector<pair<ll,ll>> q[N];

void dfs(ll x,ll fa)
{
    size[x]=c[x];
    for (ll i = 0; i < q[x].size(); i++)
    {
        ll y=q[x][i].first;
        if (y==fa) continue;
        dfs(y,x);//注意先dfs再干别的事
        size[x]+=size[y];
        qwq[x]+=qwq[y]+size[y]*q[x][i].second;
    }
}

void dp(ll x,ll fa)
{
    ll now;
    for (ll i = 0; i < q[x].size(); i++)
    {
        ll y=q[x][i].first;
        if(y==fa)continue;
        f[y]=f[x]-size[y]*q[x][i].second+(size[1]-size[y])*q[x][i].second;
        dp(y,x);
    }
}

int main()
{
    //freopen("P2986_8.in","r",stdin); //提交代码的时候把这个注释掉啊喂
    scanf("%lld",&n);
    for (ll i = 1; i <= n; i++)
        scanf("%lld",&c[i]); //草,下次注意,开了ll记得%d变%lld
    for (ll i = 1; i < n; i++)
    {
        scanf("%d%d%d",&x,&y,&temp);
        q[x].push_back(make_pair(y,temp)); //Get! make_pair(),qwq
        q[y].push_back(make_pair(x,temp));
    }
    dfs(1,0);
    f[1]=qwq[1];
    //cout<<f[1]<<" "<<size[1]<<endl;//提交代码的时候把这个注释掉啊喂
    dp(1,0);
    for (ll i = 1; i <= n; i++)
        ans=min(ans,f[i]); //留个标记,以后尝试吧这个丢到dp里面qwq
    cout<<ans<<endl;
    return 0;

}
LG P2986 [USACO10MAR]Great Cow Gathering G
comment评论
Search
search